<style lang="scss">
$border-color: #e3e3e3;
$border-width: 1px;

@mixin grid-column-style() {
  grid-template-columns: var(--z-grid-template-columns);
  grid-column-gap: var(--z-grid-column-gap, 0);
}

@mixin grid-row-style() {
  grid-row-gap: var(--z-grid-row-gap, 0);
}

@mixin grid-default-style() {
  display: grid;
  @include grid-column-style();
  @include grid-row-style();
  grid-auto-flow: row;
}


.z-table-grid--render-v2 {
  --z-table-grid-row-indicator: 0;
  .z-table-grid-column-indicator {
    height: 0;
    opacity: 0;
  }
  .z-table-grid-editor-l {
    width: 0;
    height: 0;
    opacity: 0;
  }
  .z-table-grid__action {
    display: none;
  }
  [cell-title] {
    display: none;
  }


  .z-table-grid-editor {
    --z-table-grid-column-indicator-height: 30px;
    --z-table-grid-row-indicator-width: 30px;
  }

  .z-data-grid__style-def, .z-data-grid__item-def > [data-def-cell-content] {
    display: flex;
    align-items: center;
    //justify-content: center;
  }
  .z-data-grid__item-def {
    .cm-field {
      > .el-form-item {
        margin-bottom: 0;
      }
    }
  }


  .z-table-grid-column-indicator, .z-table-grid-plc {
    height: var(--z-table-grid-column-indicator-height);
  }

  .z-table-grid-editor-wrap {
    font-size: 14px;
    //display: flex; flex-direction: row; align-items: flex-start;
    //overflow-x: auto;
    .z-table-grid-editor-c {
      //overflow-y: auto;
      //overflow-x: initial;
      height: var(--z-table-grid-editor-c-h)
    }
  }

  .z-table-grid-row-indicator {
    width: var(--z-table-grid-row-indicator-width);
  }

  .z-table-grid {
    position: relative;
  }

  .z-table-grid-body {
    border: var(--z-data-grid-bw, $border-width) solid var(--z-data-grid-bc, $border-color);
  }

  .z-table-grid-column-indicator {
    display: grid;
    @include grid-column-style();
    > * {
      display: flex;
      align-items: center;
      justify-content: center;
    }
  }

  .z-table-grid-row-indicator {
    display: grid;
    grid-template-columns:1fr;
    @include grid-row-style();
    > * {
      display: flex;
      align-items: center;
      justify-content: center;
    }
  }

  .z-table-grid-def {
    @include grid-default-style();
  }

  .z-table-grid-con-z {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    z-index: 1;
  }

  .z-table-grid-con {
    grid-template-areas: var(--z-grid-template-areas);
    z-index: 2;
  }

  .z-table-grid-height {

    grid-template-rows: var(--z-grid-template-rows);
  }

  .z-table-grid-style {
    grid-template-areas: var(--z-grid-template-style-areas);
    //pointer-events: none;
  }

  .z-table-grid-select {
    grid-template-areas: var(--z-grid-template-select-areas);
    //pointer-events: none;
  }

  .z-table-grid-def {
    --z-table-border-right: var(--z-data-grid-bw, #{$border-width}) solid var(--z-data-grid-bc, #{$border-color});
    --z-table-border-bottom: var(--z-data-grid-bw, #{$border-width}) solid var(--z-data-grid-bc, #{$border-color});
  }

  .z-table-grid-bg {
    > * {
      user-select: none;
      //border-right: var(--z-data-grid-bw, $border-width) solid var(--z-data-grid-bc, $border-color);
      border-bottom:var(--z-data-grid-bw, $border-width) solid var(--z-data-grid-bc, $border-color);
      &[islastrow] {
        border-bottom: none;
      }
      &[islastcolumn] {
        border-right: none;
      }
      &.has-style {
        border-bottom: none;
        border-right: none;
      }
    }
  }

  .z-table-grid__select-area {
    position: absolute;
    z-index: 111;
    background: rgb(1 136 251 / 35%);
    pointer-events: none;
  }
  [cell-title] {
    font-size: 12px;
    color: #999;
  }

  .z-table-grid-column {
    position: relative;
    [column-resize-trigger] {
      --column-resize-trigger-bg: transparent;
      &[moving] {
        --column-resize-trigger-bg: #3ba2f4
      }
      height: 100%;
      position: absolute;
      right: 0;
      top: 0;
      //transform: translateX(50%);
      cursor: e-resize;
      width: 6px;
      user-select: none;
      &::before {
        content: '';
        background: var(--column-resize-trigger-bg);
        width: 100%;
        height: var(--z-table-grid-column-indicator-height);
        position: absolute;
        left: 0;
        top: 0;
      }
      &::after {
        content: '';
        background: var(--column-resize-trigger-bg);
        width: 1px;
        height: 100%;
        position: absolute;
        left: 100%;
        top: 0;
      }
    }
  }

  .z-table-grid-row {
    position: relative;
    [row-resize-trigger] {
      --column-resize-trigger-bg: transparent;

      &[moving] {
        --column-resize-trigger-bg: #3ba2f4
      }

      width: 100%;
      height: 4px;
      position: absolute;
      left: 0;
      bottom: 0;
      cursor: n-resize;
      user-select: none;
      &::before {
        content: '';
        background: var(--column-resize-trigger-bg);
        height: 100%;
        width: var(--z-table-grid-row-indicator-width);
        position: absolute;
        left: 0;
        top: 0;
      }
      &::after {
        content: '';
        background: var(--column-resize-trigger-bg);
        width: 100%;
        height: 1px;
        position: absolute;
        left: 0;
        top: 100%;
      }
    }
  }

  .z-table-grid {
    width: max-content;
  }


  .z-table-grid-row-indicator {
    padding-bottom: var(--z-table-grid-row-indicator, 150px);
  }
}

</style>


<script>
import {getFieldMixinDefMap} from "../../../zform/render";
import {
  Arr,
  getAllCells,
  getSimpleCell,
  getGridAreasStyleV2,
  getRangeArrAllKeys,
  parseKeyArr,
  resolveDefPOSV2,
  toLetters
} from "./utils";
import ZDataForm from "../z-data-grid/ZDataGridForm";

function unit(v) {
  let ret = v
  if (typeof v === 'number') {
    ret = ret + 'px'
  }
  return ret
}

export default {
  name: 'ZDataGridV2',
  props: {
    def: {
      type: Object,
      default() {
        return {
        }
      }
    },
    minResizeNum: {
      type: Number,
      default: 20
    },
    defColumnSize: {
      type: String,
      default: '100px'
    },
    defRowSize: {
      type: String,
      default: '50px'
    },
    vistrualRow: {
      type: Number,
      default: 10
    },
    renderCell: {
      type: Function
    }
  },
  components: {
    ZDataForm
  },
  data() {
    return {
      eventBus: ZY_EXT.mitt(),
      controlForm: {
      },
      cachedPlaceItems: null,
      cachedItems: null,
      id: ZY.rid(),
      maxRenderRowNum: 0,
      maxRowHeight: 0,
      maxRowLeft: 0,
      cached: {
        rows: null,
        defCells: null,
        cells: null
      }
    }
  },
  inject: ['curFormCon'],
  mounted() {
    // console.log(this.def)
    this.curFormCon.importData(this.def.model);
  },
  setup(props) {

    let version = ZY.rid()

    let lastRow = ZY.lodash.get(props.def, 'lastRow', 0)
    let lastColumn = ZY.lodash.get(props.def, 'lastColumn', 0)
    let defs = ZY.lodash.get(props.def, 'defs', [])
    let styleDefs = ZY.lodash.get(props.def, 'styleDefs', [])
    let selectDefs = ZY.lodash.get(props.def, 'selectDefs', [])
    let rowSizeArr = ZY.lodash.get(props.def, 'size.row', [])
    let columnSizeArr = ZY.lodash.get(props.def, 'size.column', [])
    // let origin_data = ZY.lodash.get(props.def, 'origin.data', [])
    let origin_columnlen = ZY.lodash.get(props.def, 'origin.config.columnlen', {})
    let origin_rowlen = ZY.lodash.get(props.def, 'origin.config.rowlen', {})

    let borderInfo = ZY.lodash.get(props.def, 'origin.config.borderInfo', [])
    borderInfo.forEach(info => {
      // console.log('borderInfo', info)
      info.range.forEach(rangeItem =>  {
        let styleDef = {
          id: ZY.rid(6)
        }
        let firstPos = toLetters( rangeItem.column[0]) + rangeItem.row[0]
        let lastPos = toLetters( rangeItem.column[1]) + rangeItem.row[1]
        styleDef.range = firstPos + ':' + lastPos
        styleDef.style = {
          border: `${info.style}px solid ${info.color}`,
        }
        styleDefs.push(styleDef)
      })
    })

    function getSize(path, defVal) {
      let rowSize = ZY.lodash.get(props.def, path, defVal)
      if (typeof rowSize === 'number') {
        rowSize = rowSize + 'px'
      }
      return rowSize
    }

    let rowSize = getSize('origin.row',  props.defRowSize)
    let columnSize = getSize('origin.column',  props.defColumnSize)

    let totalHorSize = 0;
    let totalVerSize = 0;
    let totalVerSizeArr = [];
    let tmpTotalVerSize = 0;
    let maxGutter = 100000
    let rowIndexMap = new Map()

    let area = '';
    let gutterIndex = 0;
    let gutterLen = 0;

    for (let i = 0; i < lastRow + 1; i++) {
      let v = rowSize;
      if (origin_rowlen[i]) {
        v = unit(origin_rowlen[i]);
        area  = area + ` repeat(${i}, ${props.defRowSize}) ${v}`;
        gutterIndex = i;
        gutterLen = gutterLen + 1;
      }
      rowSizeArr.push(v);
      totalVerSize = totalVerSize +  parseInt(v);
      tmpTotalVerSize = tmpTotalVerSize + parseInt(v);

      let placeHolderIndex = parseInt(i / maxGutter)
      if (placeHolderIndex > totalVerSizeArr.length - 1) {
        totalVerSizeArr.push(0);
        tmpTotalVerSize = parseInt(v);
      }
      totalVerSizeArr[placeHolderIndex] = tmpTotalVerSize
      // rowIndexMap[i] = totalVerSize
      rowIndexMap.set(i + 1, totalVerSize)
    }

    // console.log(totalVerSizeArr)


    area = area + ` repeat(${rowSizeArr.length - gutterLen -  gutterIndex}, ${props.defRowSize})`;


    // console.log(area, gutterIndex)

    // origin_data[0].length
    for (let i = 0; i < lastColumn + 1; i++) {
      let v = columnSize;
      if (origin_columnlen[i]) {
        v = unit(origin_columnlen[i])
      }
      columnSizeArr.push(v);
      totalHorSize = totalHorSize + parseInt(v)
    }

    // console.log(lastRow + 1, rowSizeArr, columnSizeArr)

    let celldata = ZY.lodash.get(props.def, 'origin.celldata', [])

    let state = ZY.T.state({
      rowNum: rowSizeArr.length,
      columnNum: columnSizeArr.length,
      totalHorSize,
      totalVerSize,
      totalVerSizeArr,
      rowCssArea: area,
      columnCssArea: columnSizeArr.join(" "),
      defs: defs.map(v => {
        v.rangeArr = v.range.split(':')
        return v
      }),
      styleDefs,
      selectDefs,
      celldata,
      rowIndexMap,
      // origin:  ZY.lodash.get(props.def, 'origin', {}),
      rowSizeArr,
      columnSizeArr,
      objDefs: [],
      obj: {}
    })

    function resolveState() {
      // console.log( state.objDefs )
      if (!state.objDefs || state.objDefs.length < 1) {
        state.objDefs = state.defs.map(def => {
          def.ext = {
            arr: def.range.split(':')
          }
          def.ext.allArr = getRangeArrAllKeys(def.ext.arr[0], def.ext.arr[1])
          return def
        })
      }


      let obj = {}
      state.objDefs.forEach(def => {
        def.ext.allArr.forEach(item => {
          if (!obj[item]) {
            let [firstColumnIndex, firstRowIndex] = parseKeyArr(def.ext.arr[0])
            let [lastColumnIndex, lastRowIndex] = parseKeyArr(def.ext.arr[0])

            obj[item] = {
              id: def.id,
              def,
              firstColumnIndex,
              firstRowIndex,
              lastColumnIndex,
              lastRowIndex,
              allArr: def.ext.allArr
            }
          }
        })
        // console.log(def.ext.arr[1])
      })
      state.obj = obj
      // console.log(obj)
    }

    resolveState()

    let clsName = 'z-table-grid--' + ZY.rid(6)
    let sel = '.' + clsName

    let result;
    updateStyle({first: true})


    function updateStyle({first} = {}) {
      // if (result) {
      //   result.cssdom.parentNode.removeChild(result.cssdom)
      //   result = null
      // }
      // let areaStyle = getGridAreasStyle(state.defs, {
      //   rowNum: state.rowNum,
      //   columnNum: state.columnNum
      // }, false)
      // let styleAreaStyle = getGridAreasStyle(state.styleDefs, {
      //   rowNum: state.rowNum,
      //   columnNum: state.columnNum
      // })
      // const obj = {
      //   [sel]: {
      //     // ['--z-grid-template-areas']: areaStyle,
      //     // ['--z-grid-template-style-areas']: styleAreaStyle,
      //   }
      // }

      // if (!first) {
      //   obj[sel]['--z-grid-template-select-areas'] = getGridAreasStyle(state.selectDefs, {
      //     rowNum: state.rowNum,
      //     columnNum: state.columnNum
      //   })
      // }
      // result = ZY_EXT.cssobj(obj);
    }

    // console.log(areasStyle)

    return {
      result,
      version,
      updateStyle,
      resolveState,
      clsName,
      state,
    }
  },
  methods: {
    $_defColumnSize() {
      // let column = ZY.lodash.get(this.state.origin, 'column', -1)
      // if (column > -1) {
      //   return column + 'px'
      // }
      // return this.defColumnSize
    },
    $_defRowSize() {
      // let row = ZY.lodash.get(this.state.origin, 'row', -1)
      // if (row > -1) {
      //   return row + 'px'
      // }
      // return this.defRowSize
    },
    appendColumn() {
      let newArr = Arr(this.controlForm.num).map(() => this.$_defColumnSize())
      this.state.columnSizeArr = this.state.columnSizeArr.concat(newArr)
      this.state.columnNum = this.state.columnSizeArr.length
    },
    appendRow() {
      // this.state.rowSizeArr.push(this.defRowSize)
      let newArr = Arr(this.controlForm.num).map(() => this.$_defRowSize())
      this.state.rowSizeArr = this.state.rowSizeArr.concat(newArr)
      this.state.rowNum = this.state.rowSizeArr.length
    },
    $_offset(containerSelector = '.z-table-grid-editor-content') {
      let container = this.getContainer()
      let containerRect = container.querySelector(containerSelector).getBoundingClientRect()
      return containerRect
    },
    $_GetPos(target, containerSelector = '.z-table-grid-editor-content') {
      let container = this.getContainer()
      let containerRect = container.querySelector(containerSelector).getBoundingClientRect()
      let cellStyle = this.getFirstCellStyle()
      let borderRight = parseFloat(cellStyle.borderRight);
      let borderBottom = parseFloat(cellStyle.borderBottom);

      let rect = target.getBoundingClientRect();
      let top = rect.top - containerRect.top - (borderBottom < 1 ? 1 : borderBottom);
      let left = rect.left - containerRect.left - (borderRight < 1 ? 1 : borderRight);
      let width = rect.width
      let height = rect.height
      let lastLeft = (left + width)
      let lastBottom = (top + height)
      return {
        left, top, width: rect.width, height: rect.height, lastLeft, lastBottom
      }
    },
    toLetters,
    getContainer() {
      return document.getElementById(this.id)
    },
    getFirstCellStyle() {
      let container = this.getContainer()
      // console.log(container.getBoundingClientRect())
      let cell = container.querySelector('.z-table-grid-editor__cell:first-child')
      return  window.getComputedStyle(cell);
    },
    renderRowIndicator() {
      let self = this
      let moving = false
      let cur = null

      function handleMouseMove(e) {
        if (moving) {
          // console.log(e)
          let newVal = (e.pageY -  cur.target.parentElement.getBoundingClientRect().top)
          if (newVal < self.minResizeNum) {
            newVal = self.minResizeNum
          }
          cur.target.style.top = newVal + 'px'
          cur.newVal = newVal
        }
      }

      function handleMouseUp(e) {
        if (moving) {
          moving = false
          cur.target.style.width = '100%'
          cur.target.style.zIndex = null
          let newVal = cur.target.style.top
          cur.target.style.top = null
          cur.target.removeAttribute('moving')
          cur.target.parentElement.style.userSelect = null
          // console.log(cur)
          self.state.rowSizeArr[cur.index] = newVal
          // console.log(self.state.columnSizeArr)
          self.eventBus.emit('resize')
          self.version = ZY.rid()
          cur = null
        }
      }

      let col = Arr(this.state.rowNum).map((v, i) => {

        function handleMouseDown(e) {
          // console.log(e)
          moving = true
          cur = {
            v,
            target: e.target,
            index: i
          }
          let container = self.getContainer()
          e.target.setAttribute('moving', 1)
          e.target.style.width = container.clientWidth + 'px'
          e.target.style.zIndex = 1111
          e.target.parentElement.style.userSelect = 'none'
          // let pos = self.$_GetPos(e.target)
          // console.log(container.clientHeight, pos)
        }



        return  ( <div class="z-table-grid-row">{i+1}
          <div
              onMousedown={handleMouseDown}
              row-resize-trigger>&nbsp;</div></div>)
      })
      return (
          <div class="z-table-grid-row-indicator" onMouseup={handleMouseUp} onMousemove={handleMouseMove}>
            {col}
          </div>
      )
    },
    renderColumnIndicator() {
      let self = this
      let moving = false
      let cur = null

      function handleMouseMove(e) {
        if (moving) {
          // console.log(e)
          let newVal = (e.pageX -  cur.target.parentElement.getBoundingClientRect().left)
          if (newVal < self.minResizeNum) {
            newVal = self.minResizeNum
          }
          cur.target.style.left = newVal + 'px'
          cur.newVal = newVal
        }
      }

      function handleMouseUp(e) {
        if (moving) {
          moving = false
          cur.target.style.height = '100%'
          cur.target.style.zIndex = null
          let newVal = cur.target.style.left
          cur.target.style.left = null
          cur.target.removeAttribute('moving')
          cur.target.parentElement.style.userSelect = null
          // console.log(cur)
          self.state.columnSizeArr[cur.index] = newVal
          // console.log(self.state.columnSizeArr)
          self.eventBus.emit('resize')
          self.version = ZY.rid()
          cur = null
        }
      }

      let col = Arr(this.state.columnNum).map((v, i) => {

        function handleMouseDown(e) {
          // console.log(e)
          moving = true
          cur = {
            v,
            target: e.target,
            index: i
          }
          let container = self.getContainer()
          e.target.setAttribute('moving', 1)
          e.target.style.height = container.clientHeight + 'px'
          e.target.style.zIndex = 1111
          e.target.parentElement.style.userSelect = 'none'
          // let pos = self.$_GetPos(e.target)
          // console.log(container.clientHeight, pos)
        }

        return  ( <div class="z-table-grid-column">{toLetters(i+1)} <div
            onMousedown={handleMouseDown}
            column-resize-trigger>&nbsp;</div></div>)
      })
      return (
          <div class="z-table-grid-column-indicator" onMouseup={handleMouseUp} onMousemove={handleMouseMove}>{col}</div>
      )
    },
    setSelectDefs(firstKey, lastKey = firstKey) {
      this.state.selectDefs[0] = resolveDefPOSV2({
        "id": ZY.rid(6),
        "range": `${firstKey}:${lastKey}`,
        // letterSingle: "A2",
        // style: {
        //
        // },
        // isSingle: true
        // cArr: [0,0],
        // rArr: [3,3]
      })
      this.$nextTick(() => {
        this.version = ZY.rid()
        this.updateStyle()
      })
      // console.log(' this.state.selectDefs',  this.state.selectDefs)
    },
    renderSelectItems() {
      let self = this
      let lastRowKey = this.state.rowNum
      let lastColumnKey = toLetters(this.state.columnNum);
      let selectDefs = self.state.selectDefs
      // console.log(selectDefs)
      return selectDefs.map(v => {

        let styleMap = ZY.lodash.get(v, 'style')
        // console.log(styleMap)
        let styleObj = {
          ['grid-area']: v.id + "",
          ...styleMap
        }
        let rangeArr = v.range.split(':')


        let [lastColumnNum, lastRowIndex, lastColumnLetter] = parseKeyArr(rangeArr[1])
        let islastrow = lastRowIndex >= lastRowKey
        let islastcolumn = lastColumnLetter === lastColumnKey

        // console.log(islastrow)
        return (<div  style={styleObj}
                     data-key={rangeArr[0]}
                     data-last-key={rangeArr[1]}
                     data-row-num={lastRowIndex}
                     data-column-num={lastColumnNum}
                     class="z-data-grid__select-def"
                     islastcolumn={islastcolumn} islastrow={islastrow}></div>)
      })
    },
    renderStyleItems() {
      let self = this
      let lastRowKey = this.state.rowNum
      let lastColumnKey = toLetters(this.state.columnNum)
      let handleClick = self.handleCellClick();

      return self.state.styleDefs.map(v => {

        let styleMap = ZY.lodash.get(v, 'style')
        // console.log(styleMap)
        let styleObj = {
          ['grid-area']: v.id + "",
          ...styleMap
        }
        let rangeArr = v.range.split(':')


        let [lastColumnNum, lastRowIndex, lastColumnLetter] = parseKeyArr(rangeArr[1]);
        let islastrow = lastRowIndex >= lastRowKey;
        let islastcolumn = lastColumnLetter === lastColumnKey;


        // console.log(islastrow)
        return (<div data-grid-cell="1" style={styleObj}
                     data-key={rangeArr[0]}
                     data-last-key={rangeArr[1]}
                     data-row-num={lastRowIndex}
                     data-column-num={lastColumnNum}
                     class="z-data-grid__style-def"
                     onClick={handleClick}
                     islastcolumn={islastcolumn} islastrow={islastrow}></div>)
      })
    },
    renderItems({placeholder = false, idArr = []} = {}) {
      let fieldMixinDefMap = getFieldMixinDefMap()
      let curFormCon = this.curFormCon

      let self = this
      // let lastRowKey = this.state.rowNum
      // let lastColumnKey = toLetters(this.state.columnNum)
      return self.state.defs.map((v, i) => {
        let cellDataInfo = {}
        if (v.cell) {
          cellDataInfo = v.cell
        }
        // let {rowLineNum, columnNum} = getSimpleCell(i, this.state.rowNum, this.state.columnNum)

        // let cellDataInfo = self.getCellDataInfo(columnNum - 1, rowLineNum - 1)
        // console.log(cellDataInfo, columnNum - 1, rowLineNum)

        let styleDef = self.state.styleDefs.find(def => def.range === v.range)
        if (styleDef) {
          // console.log(styleDef)
        }
        let handleClick = self.handleCellClick()
        let handleMouseMove = self.handleCellMouseMove()
        let handleMouseUp = self.handleCellMouseUp()
        let styleObj = {
          ['grid-area']: v.id + ""
        }
        let subStyleObj = {}

        // 样式
        let fc = ZY.lodash.get(cellDataInfo, 'v.fc')
        if (fc) {
          styleObj['color'] = fc
        }
        let fs = ZY.lodash.get(cellDataInfo, 'v.fs')
        if (fs) {
          styleObj['fontSize'] = fs + 'px'
        }
        let bg = ZY.lodash.get(cellDataInfo, 'v.bg')
        if (bg) {
          styleObj['backgroundColor'] = bg
        }
        // console.log(bg, cellDataInfo.c, cellDataInfo.r)
        let bl = ZY.lodash.get(cellDataInfo, 'v.bl', 0)
        if (bl) {
          styleObj['fontWeight'] = 'bold'
        }
        let it = ZY.lodash.get(cellDataInfo, 'v.it', 0)
        if (it) {
          styleObj['fontStyle'] = 'italic'
        }
        let cl = ZY.lodash.get(cellDataInfo, 'v.cl', 0)
        if (cl) {
          styleObj['textDecoration'] = 'line-through'
        }
        let ul = ZY.lodash.get(cellDataInfo, 'v.ul', 0)
        if (ul) {
          subStyleObj['textDecoration'] = 'underline'
        }
        let ht = ZY.lodash.get(cellDataInfo, 'v.ht')
        if (typeof ht !== 'undefined') {
          // ht 1 top-left
          // ht 0 top-center
          // ht 2 top-right
          // vt: "0"
          let obj = {
            ['1']: 'flex-start',
            ['0']: 'center',
            ['2']: 'flex-end',
          }
          styleObj['display'] = 'flex'
          styleObj['justifyContent'] = obj[ht]
        }

        let vt = ZY.lodash.get(cellDataInfo, 'v.vt')
        if (typeof vt !== 'undefined') {
          let obj = {
            ['1']: 'flex-start',
            ['0']: 'center',
            ['2']: 'flex-end',
          }
          styleObj['display'] = 'flex'
          styleObj['alignItems'] = obj[vt]
        }

        let rangeArr = v.range.split(':')
        // let lastColumnLetter = rangeArr[1].slice(0,1)
        // let lastColumnNum = convertLetterToNumber(lastColumnLetter)
        // let lastRowIndex = parseInt(rangeArr[1].slice(1))

        let [lastColumnNum, lastRowIndex, lastColumnLetter] = parseKeyArr(rangeArr[1])
        // let islastrow = lastRowIndex >= lastRowKey
        // let islastcolumn = lastColumnLetter === lastColumnKey

        let classObj = {
          ["z-data-grid__item-def"]: 1
        }

        if (styleDef) {
          let border = ZY.lodash.get(styleDef, 'style.border')
          if (border) {
            classObj['has-style'] =1
          }
        }


        let cmFieldConfig = ZY.lodash.get(v, 'config')
        let widget = ZY.lodash.get(v, 'config.ui.widget');
        let ui = ZY.lodash.get(v, 'config.ui', {});
        let fieldName = ZY.lodash.get(v, 'config.fieldName', {});
        let pathArr = [fieldName]
        let _content = v.content ?? ''

        let iscustom = false;
        let content;

        if (placeholder) {
          content = (<div style={subStyleObj}>{_content}</div>)
        } else {
          if (widget && fieldMixinDefMap.has(widget)) {
            // let def = fieldMixinDefMap.get(widget).create(widgetConfig)
            // console.log(def)
            iscustom = true
            // console.log(v)
            let defVal = ui?.defVal
            // console.log(fieldName)
            content = (<cm-field noLabel={true} prop={fieldName}
                                 pathArr={pathArr}
                                 modelValue={defVal}
                                 prop_config={cmFieldConfig}
                                 onValchange={onValueChange}></cm-field>)
          } else {
            content = (<div style={subStyleObj}>{_content}</div>)
          }
        }

        function onValueChange( e) {
          // console.log('onValueChange', curFormCon, e)
          curFormCon.updateValue('', [fieldName], e)
        }

        // console.log(islastrow)

        let isInShow = idArr.includes(v.id)

        return (<div data-grid-cell="1" isInShow={isInShow} data-def-cell sel={v.id} style={styleObj} class={classObj}
                     onMousemove={handleMouseMove} onMouseup={handleMouseUp}
                     iscustom={iscustom}
                     data-key={rangeArr[0]}
                     data-last-key={rangeArr[1]}
                     data-row-num={lastRowIndex}
                     data-column-num={lastColumnNum}
                   >
          <div   data-key={rangeArr[0]}
                 data-last-key={rangeArr[1]}   onMousedown={handleClick} data-def-cell-content>{content}</div>
        </div>)
      })
    },
    getCellDataInfo(c, r) {
      return  this.state.celldata.find(v => {
        return v.r === r && v.c === c
      })
    },
    /**
     * 渲染rows
     * @param maxRow
     * @param start
     * @param flag
     * @returns {unknown[]}
     */
    renderRows({maxRow, start = 0, flag = false} = {}) {
      let self = this;
      let TotalColumnNum = this.state.columnNum
      let rowNum = maxRow ?? this.state.rowNum
      let renderItemsSize = rowNum * 1;
      let indexArr = Arr(renderItemsSize).map((v, i) => {
        return {
          v,
          index: i + start
        }
      });

      let col = indexArr.map(item => {
        let index = item.index;
        let rowLineNum = index + 1;
        let isEven = rowLineNum % 2 === 0;

        let c = Arr(TotalColumnNum).map((v, colIndex) => {
          let content = (<div class="z-table-grid-editor__row-cell">&nbsp;</div>)
          if (self.renderCell) {
            let  a  = self.renderCell({isEven, rowLineNum, columnNum: colIndex + 1, index: index * TotalColumnNum + colIndex})
            content = (
                <div class="z-table-grid-editor__row-cell">{a}</div>
            )
          }

          return content
        })

        return  ( <div class="z-table-grid-editor__row"
                       even={isEven}  row-line={rowLineNum}
                       data-row-num={rowLineNum}
        >{c}</div>)
      });

      return col;
    },
    handleMouseEnter(e) {
      let target = e.target;
      // console.log('handleMouseEnter', target.dataset)
      // let rowNum = parseInt(target.dataset.rowNum)
      if (!this.cached.rows) {
        this.cached.rows = this.$el.querySelectorAll('.z-table-grid-editor__row');
      }
      let rows = this.cached.rows;
      // if (rows) {
      //   [...rows].forEach(row => {
      //     row.classList.remove('current-row');
      //     if (row.dataset.rowNum === target.dataset.rowNum) {
      //       row.classList.add('current-row');
      //     }
      //   })
      // }
      if (!this.cached.cells) {
        this.cached.cells = this.$el.querySelectorAll('.z-table-grid-editor__cell');
      }
      let cells = this.cached.cells;
      // if (cells) {
      //   [...cells].forEach(cell => {
      //     cell.classList.remove('is-in-current-row');
      //     if (cell.dataset.rowNum === target.dataset.rowNum) {
      //       cell.classList.add('is-in-current-row');
      //     }
      //   })
      // }
      // console.log(rows)
    },
    getCacachedCells() {
      if (this.cached.defCells) {
        return this.cached.defCells
      } else {
        let {cells} = getAllCells(this.state.defs);
        this.cached.defCells = cells;
        return cells;
      }
    },
    renderTable({maxRow, start = 0, flag = false} = {}) {
      let self = this;

      let handleMouseEnter = self.handleMouseEnter;
      // console.log('start', start)

      // let rowSizeArrLength = this.state.rowSizeArr.length;
      // let columnLength = this.state.columnSizeArr.length;
      let cells = this.getCacachedCells();
      // console.log('isInRange', isInRange)

      let rowNum = maxRow ?? this.state.rowNum
      let renderItemsSize = rowNum * this.state.columnNum;
      // let endIndex =  start + renderItemsSize;
      // let isSuperPower = false;
      let indexArr = []
      // if (endIndex > rowSizeArrLength *  this.state.columnSizeArr.length ) {
      //   // console.log('wocao')
      //   isSuperPower = true;
      //
      //   for (let m = rowSizeArrLength - 10; m < rowSizeArrLength; m++) {
      //     for (let n = 0; n < columnLength; n++) {
      //       indexArr.push({
      //         v: {},
      //         index: m * columnLength + n
      //       })
      //     }
      //   }
      // } else {
      //   indexArr = Arr(renderItemsSize).map((v, i) => {
      //     return {
      //       v,
      //       index: i + start
      //     }
      //   })
      // }
      // indexArr = Arr(renderItemsSize).map((v, i) => {
      //   return {
      //     // v,
      //     index: i + start
      //   }
      // })
      indexArr = Arr(renderItemsSize)
      // console.log(start, renderItemsSize,  this.state.rowNum)

      return indexArr.map((v, i) => {
        // let index = item.index;
        let index =  i + start;
        // let v = item.v;
        let {rowLineNum, columnNum, letter, key} = getSimpleCell(index, this.state.rowNum, this.state.columnNum);
        let isEven = rowLineNum % 2 === 0;
        // console.log(i, letter + rowLineNum)

        // let relLine = Math.ceil(i / this.state.columnNum) === rowNum
        // let styleObj = {}
        // // let cellDataInfo = self.getCellDataInfo(columnNum, rowLineNum)
        // let cellDataInfo = v?.cell ?? {}
        // if (cellDataInfo) {
        //   // console.log(cellDataInfo)
        //   if (cellDataInfo?.v?.bg) {
        //     styleObj.backgroundColor = cellDataInfo?.v?.bg
        //   }
        // }

        let isInCell = cells.includes(key);
        //  <div cell-title>{letter}{rowLineNum}</div>


        // <div>{index + 1}</div>
        let c = ''
        // if (flag) {
        //   c =
        //       (
        //           <div>
        //             {letter + rowLineNum}
        //           </div>
        //       )
        // }

        return (<div data-grid-cell="1" class="z-table-grid-editor__cell"
                      row-line={rowLineNum} column-num={columnNum}
                     data-is-in={isInCell}
                     data-key={key}
                     data-last-key={key}
                     data-row-num={rowLineNum}
                     data-column-num={columnNum}
                     onMouseenter={handleMouseEnter}
        >{c}</div>)
      })
    },
    handleCellClick() {
      // alert(1)
      let self = this;
      return function (e) {
        // console.log('sdsds')
        self.$emit('cell-click', {
          ctx: self,
          shiftKey: e.shiftKey,
          target: e.target
        })
        // if (self.selectHandleCellClick) {
        //   self.selectHandleCellClick(e)
        // }
      }
    },
    handleCellMouseMove() {
      // alert(1)
      let self = this
      return function (e) {
        if (self.selectHandleCellMouseMove) {
          self.selectHandleCellMouseMove(e)
        }
      }
    },
    handleCellMouseUp() {
      // alert(1)
      let self = this
      return function (e) {
        if (self.selectHandleCellMouseUp) {
          self.selectHandleCellMouseUp(e)
        }
      }
    },
    handleCellMouseDown() {
      // alert(1)
      let self = this
      return function (e) {
        if (self.selectHandleCellMouseDown) {
          self.selectHandleCellMouseDown(e)
        }
      }
    },
    handleMenu(type) {
      let self = this
      return function () {
        // console.log('sdsdsds')
        self.state.defs.push(  {
          id: 'label' + ZY.rid(6),
          range: self.selectState.areaRange.join(':')
        })
        self.$nextTick(() => {
          self.resolveState()
          self.updateStyle()
        })
      }
    },
    forceRender() {
      this.version = ZY.rid()
    },
    /**
     *
     * @param x
     */
    scrollToRowLine(x) {
      let self = this;
      // let defRowSizeV = parseInt(self.defRowSize)
      window.requestAnimationFrame(function () {
        self.maxRenderRowNum = x;
        self.maxRowHeight = x * 50;
        let item = self.state.rowIndexMap.get(x)
        // console.log(item)
        self.version = ZY.rid()
      })
    },
    handleOnScroll(e) {
      let self = this;
      // return;
      // let oldmaxRowHeight = self.maxRowHeight;

      if ( e.target.scrollTop ===  self.maxRowHeight) {
        if (self.maxRowLeft !== e.target.scrollLeft) {
          self.maxRowLeft = e.target.scrollLeft;
          return;
        }
      }
      let defRowSizeV = parseInt(self.defRowSize)

      // let isDown = e.target.scrollTop > oldmaxRowHeight

      self.maxRowLeft = e.target.scrollLeft;
      self.maxRowHeight = e.target.scrollTop;
      let totalVerSize = this.state.totalVerSize;

      // console.log(totalVerSize)
      // console.log(e)
      window.requestAnimationFrame(function () {
        if (e.target.scrollTop > totalVerSize) {
          self.maxRenderRowNum = self.state.rowSizeArr.length - 1
        } else {
          // let x = 0;
          // for (let [index, item] of  Object.entries(self.state.rowIndexMap)) {
          //   if (item > e.target.scrollTop) {
          //     x = parseInt(index);
          //     break;
          //   }
          // }
          // for (let i = 0; i < self.state.rowSizeArr.length; i++) {
          //   let item = self.state.rowIndexMap.get(i)
          //   console.log(item);
          //   if (item > e.target.scrollTop) {
          //     break;
          //   }
          // }


// console.log(e.target.scrollTop > oldmaxRowHeight )

    let s = parseInt(e.target.scrollTop / defRowSizeV);
// console.log(s, e.target.scrollTop)

          if (s < 1) {
            self.maxRenderRowNum = 0
            return;
          }

          if (s < 100) {
            self.maxRenderRowNum = s
            return;
          }


          let x = 0;

          for (let i = s - 100; i < s + 100; i++) {
              let item = self.state.rowIndexMap.get(i)
              // console.log(item);
              if (item > e.target.scrollTop) {
                x = i;
                break;
              }
            }

          // if (isDown) {


          //   for (let i = self.maxRenderRowNum; i < self.state.rowSizeArr.length; i++) {
          //     let item = self.state.rowIndexMap.get(i)
          //     // console.log(item);
          //     if (item > e.target.scrollTop) {
          //       x = i;
          //       break;
          //     }
          //   }
          // } else {

          //   for (let i = s - 100; i < s + 100; i++) {
          //     let item = self.state.rowIndexMap.get(i)
          //     // console.log(item);
          //     if (item > e.target.scrollTop) {
          //       x = i;
          //       break;
          //     }
          //   }

          //   //  x = parseInt(e.target.scrollTop / 50);
          // }

          self.maxRenderRowNum = x
        }

        self.version = ZY.rid()
      });
    },
    handleScrollWheel(e) {
      this.$emit('grid-wheel', e)
    },
    getCachedPlaceItems() {
      if (!this.cachedPlaceItems) {
        let placeItems = this.renderItems({placeholder: true});
        this.cachedPlaceItems = placeItems
        return placeItems
      } else {
        return this.cachedPlaceItems
      }
    },
    getCachedItems() {
      if (!this.cachedItems) {
        let placeItems = this.renderItems();
        this.cachedItems = placeItems
        return placeItems
      } else {
        return this.cachedItems
      }
    }
  },
  render(h) {
    let self = this;
    // let $__renderRowIndicator = this.renderRowIndicator()
    // let $__renderColumnIndicator = this.renderColumnIndicator();

    let vistrualRow = self.vistrualRow;
    let maxRenderRowNum = self.maxRenderRowNum;
    let $__renderTable = this.renderTable({ maxRow: self.vistrualRow, start: maxRenderRowNum  * this.state.columnNum, flag: false });
    let $__renderRows = this.renderRows({ maxRow: self.vistrualRow, start: maxRenderRowNum , flag: false });
    // let placeItems = this.getCachedPlaceItems()
    // let selectItems = this.renderSelectItems()
    // let styleItems = this.renderStyleItems()
    // let handleMouseDown = this.handleCellMouseDown()

    // let opt = {}
    // if (this.renderSelectArea) {
    //    opt = this.renderSelectArea()
    // }
    // console.log('call render')

    // let columnSizeArr = this.state.columnSizeArr;
    let rowSizeArr = this.state.rowSizeArr;
    let handleOnScroll = this.handleOnScroll;

    let curSizeArr = [];
    if (maxRenderRowNum + vistrualRow > rowSizeArr.length) {
      curSizeArr = rowSizeArr.slice(-vistrualRow)
    } else {
      curSizeArr = rowSizeArr.slice(maxRenderRowNum, maxRenderRowNum + vistrualRow)
    }
    // console.log(
    //     'curSizeArr', curSizeArr, maxRenderRowNum
    // )

    let bgStyle = {
      ['grid-template-rows']: curSizeArr.join(' ')
    }

    let style = {
      "--z-grid-template-columns": this.state.columnCssArea,
      // "--z-grid-template-rows": rowSizeArr.join(" "),
      // "--z-grid-template-rows": this.state.rowCssArea,
    }
    let classObj = 'z-table-grid-editor z-table-grid--edit ' + this.clsName


    let handleScrollWheel = this.handleScrollWheel

    // let appendRow = this.appendRow
    // let appendColumn = this.appendColumn
    // let controlForm = this.controlForm

    // function handleControlForm(type) {
    //   return function (newVal) {
    //     controlForm[type] = newVal
    //   }
    // }

    // let handleClick = self.handleCellClick();

    // let bgStyle = {
    //   transform: `translateY(${maxRowHeight}px)`
    // }



// console.log(maxRenderRowNum)

    let gridRes = getGridAreasStyleV2(this.state.defs, {
      startRowNum: maxRenderRowNum,
      maxRowSize: rowSizeArr.length,
      rowNum: vistrualRow,
      columnNum: this.state.columnNum
    }, false);
    let idArr = [...new Set(gridRes.finded)]
    // console.log(idArr)
    let itemStyle = {
      ...bgStyle,
      'grid-template-areas': gridRes.style
    }

    let items = this.renderItems({idArr})


    // let placeDivs = (<div>&nbsp;</div>)
    let placeDivs = this.state.totalVerSizeArr.map(itemheight => {
      let placeStyle = {
        ['height']: itemheight + 'px'
      }
      return (<div style={placeStyle}>&nbsp;</div>)
    })



// <div class="z-table-grid-def z-table-grid-con-z z-table-grid-height z-table-grid-con"
//                     >
//                       {placeItems}
//                     </div>

    // <div class="z-table-grid-def z-table-grid-con-z z-table-grid-height z-table-grid-con"
    //
    // >
    //   {items}
    // </div>

    // <div className="z-table-grid-def z-table-grid-con-z z-table-grid-style">
    //   {styleItems}
    // </div>
    // <div className="z-table-grid-def z-table-grid-con-z z-table-grid-height z-table-grid-select"
    // >
    //   {selectItems}
    // </div>

              // <el-input-number max={100} value={controlForm.num} onInput={handleControlForm('num')}></el-input-number>
              // <el-button onClick={appendRow}>appendRow</el-button>
              // <el-button onClick={appendColumn}>appendColumn</el-button>

    return (
        <div id={this.id} class="z-table-grid--render-v2" ver={this.version}>
          <div class={classObj}
               style={style}
          >
            <div class="z-table-grid__action">

            </div>
            <div class="z-table-grid-editor-wrap">
              <div class="z-table-grid-editor-l">
                <div class="z-table-grid-plc"></div>
              </div>
              <div class="z-table-grid-body"
                   style="overflow: overlay"
                   onScroll={handleOnScroll}
                   onWheel={handleScrollWheel}
              >
                <div class="z-table-grid-sti">
                  <div class="z-table-grid-def z-table-grid-height z-table-grid-bg"
                       style={bgStyle}
                  >
                    {$__renderTable}
                  </div>
                  <div class="z-table-grid-def z-table-grid-height z-table-grid-row-bg"
                       style={bgStyle}
                  >
                    {$__renderRows}
                  </div>
                  <div class="z-table-grid-def z-table-grid-height  z-table-grid-bg2"
                  style={itemStyle}
                  >{items}</div>
                </div>
                <div class="z-table-grid-editor-c">
                  <div class="z-table-grid z-table-grid-editor-content">
                    {placeDivs}
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
    )
  }
}
</script>
